﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using System.IO.Compression;
using System.Collections;

namespace Rdz.Utility
{
	public static class StringUtility
	{
		/// <summary>
		/// Slice string based on size criteria.
		/// </summary>
		/// <param name="InputString">Specifies the string to be sliced.</param>
		/// <param name="SlicedSize">Specifies the slice size in comma separated string. Ex: "3,7,2" means that first slice is 3, 7 and then 2 characters length.</param>
		/// <returns>Returns Array of strings after slice.</returns>
		public static string[] SliceString(this string InputString, string SlicedSize)
		{
			List<string> sRet = new List<string> { };
			string[] Size = SlicedSize.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
			int Pointer = 0;

			foreach (string Sz in Size)
			{
				try
				{
					sRet.Add(InputString.Substring(Pointer, int.Parse(Sz)));
					Pointer += int.Parse(Sz);
				} catch { }
			}

			return sRet.ToArray();
		}

		/// <summary>
		/// Slice string based on size criteria.
		/// </summary>
		/// <param name="InputString">Specifies the string to be sliced.</param>
		/// <param name="SlicedSize">Specifies the slice size in array of integer. Ex: new int[] { 3, 7, 2 } means that first slice is 3, 7 and then 2 characters length.</param>
		/// <returns></returns>
		public static string[] SliceString(this string InputString, int[] SlicedSize)
		{
			List<string> sRet = new List<string> { };
			int Pointer = 0;

			foreach (int Size in SlicedSize)
			{
				try
				{
					sRet.Add(InputString.Substring(Pointer, Size));
					Pointer += Size;
				} catch { }
			}

			return sRet.ToArray();
		}

		/// <summary>
		/// Compress string using GZip Compression
		/// </summary>
		/// <param name="InputString">Specifies the string to be compressed.</param>
		public static string GZipCompress(this string InputString)
		{
			byte[] InputByte = UTF8Encoding.UTF8.GetBytes(InputString);
			using (MemoryStream sw = new MemoryStream())
			{
				using (GZipStream gz = new GZipStream(sw, CompressionMode.Compress))
				{
					gz.Write(InputByte, 0, InputByte.Length);
					gz.Close();
					InputByte = sw.ToArray();
					return UTF8Encoding.UTF8.GetString(InputByte);
				}
			}
		}

		/// <summary>
		/// Decompress string using GZip Compression
		/// </summary>
		/// <param name="InputString">Specifies the string to be decompressed.</param>
		public static string GZipDecompress(this string InputString)
		{
			byte[] InputByte = UTF8Encoding.UTF8.GetBytes(InputString);
			using (MemoryStream sw = new MemoryStream(InputByte))
			{
				using (GZipStream gz = new GZipStream(sw, CompressionMode.Decompress))
				{
					gz.Close();
					InputByte = sw.ToArray();
					return UTF8Encoding.UTF8.GetString(InputByte);
				}
			}
		}

		/// <summary>
		/// Replaces the format item in a specified string with the string representation of a corresponding object in a specified hashtable.
		/// </summary>
		/// <param name="format">A composite format string. Format with double square-brackets with name inside. i.e.: string format = "My Name is [[name]]";</param>
		/// <param name="args">A hashtable that contains zero or more objects to format. You can create case-insensitive Hashtable by providing System.StringComparer.CurrentCultureIgnoreCase as the constructor's argument.</param>
		/// <returns>A copy of format in which the format items have been replaced by the string representation of the corresponding objects in args.</returns>
		public static string Format(this string format, Hashtable args)
		{
			
			string input = format;
			string str2 = "[[{0}]]";
			Regex regex = new Regex(@"(?<=\[\[)[^\[\]][a-zA-Z0-9]+(?=\]\])");
			if (regex.IsMatch(input))
			{
				MatchCollection matchs = regex.Matches(input);
				foreach (Match match in matchs)
				{
					if (args.ContainsKey(match.Value))
					{
						string newValue = args[match.Value] as string;
						input = input.Replace(string.Format(str2, match.Value), newValue);
					}
				}
			}
			return input;
		}
	}
}
